import 'dart:async';
import 'dart:io';
import 'package:common/utils/date_util.dart';
import 'package:common/utils/device_util.dart';
import 'package:common/utils/log.dart';
import 'package:common/utils/object_util.dart';
import 'package:common/utils/path_util.dart';
import 'package:flutter/material.dart';

class AppLaunch {
  static Future<void> run<T>(T Function() callback) async {
    catchException(() => callback);
  }

  /// 异常捕获处理
  static void catchException<T>(T Function() callback) {
    //捕获异常的回调,runZonedGuarded是可以捕获一个作用域未被捕获的异常
    runZonedGuarded(() {
      callback();
    }, (error, stackTrace) {
      var details = makeDetails(error, stackTrace);
      //异常上报
      reportErrorAndLog(details);
      //异常打印
      logger.e(details);
    }, zoneSpecification: ZoneSpecification(
      print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
        collectLog(parent, zone, line); // 收集日志
      },
    ));
  }

  ///日志拦截, 收集日志
  static void collectLog(ZoneDelegate parent, Zone zone, String line) {
    parent.print(zone, line);
  }

  ///上报错误和保存本地日志
  static void reportErrorAndLog(FlutterErrorDetails details) {
    debugPrint(details.toStringShort());
    saveErrorToFile(details.toString());
  }

  ///以文本方式把报错信息保存到本地,仅适用于Android和IOS
  static Future<void> saveErrorToFile(String error) async {
    //判断是否手机,假如不是手机停止执行
    if (!DeviceUtil.isMobile) {
      return;
    }
    //获取应用存储目录
    String? dirPath = '';
    if (DeviceUtil.isIOS) {
      dirPath = await PathUtils.getCacheDirPath();
      if (ObjectUtil.isEmpty(dirPath)) {
        return;
      }
    } else {
      dirPath = await PathUtils.getExternalCacheDirPath();
      if (ObjectUtil.isEmpty(dirPath)) {
        return;
      }
    }
    //创建 crash的文件夹
    Directory? crashDir = PathUtils.createDirSync('$dirPath/crash');
    String? crashDirPath = crashDir?.path;
    if (ObjectUtil.isEmpty(dirPath)) {
      return;
    }
    //创建文本
    String fileName = 'crash_${DateUtil.getNowDateStr()!.replaceAll(' ', '_')}.txt';
    File file = File('$crashDirPath/$fileName');
    if (!file.existsSync()) {
      file.createSync();
    }

    logger.i("异常文本路径:${file.path}");
    //把信息写入文本信息
    file.writeAsString(error);
  }

  ///构建错误信息
  static FlutterErrorDetails makeDetails(Object obj, StackTrace stack) {
    return FlutterErrorDetails(exception: obj, stack: stack);
  }

}
